package com.ponhu.ea2.goodsCenter.provider.facade.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.ponhu.ea2.entity.GoodsDataCreateorupdateLog;
import com.ponhu.ea2.entity.Inventory;
import com.ponhu.ea2.entity.PhBrand;
import com.ponhu.ea2.entity.PhCategory;
import com.ponhu.ea2.enums.YesOrNoEnum;
import com.ponhu.ea2.goodsCenter.provider.service.GoodsDataCreateorupdateLogService;
import com.ponhu.ea2.goodsCenter.provider.service.InventoryService;
import com.ponhu.ea2.goodsCenter.provider.service.PhBrandService;
import com.ponhu.ea2.goodsCenter.provider.service.PhCategoryService;
import com.ponhu.ea2.goodsCenter.provider.utils.DingTalkHandler;
import com.ponhu.ea2.goodsCenter.provider.utils.ReqEncryptUtil;
import com.ponhu.ea2.service.facade.GoodsCenterForChuangjiService;
import com.ponhu.ea2.service.facade.InventoryApiService;
import com.ponhu.ea2.vo.PhInventoryAccessoryVo;
import com.ponhu.ea2.vo.PhInventoryDetailVo;
import com.ponhu.ea2.vo.PhPropertyVo;
import com.ponhu.ea2.vo.SignProp;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author luyu
 * @create 2022-01-13 11:55
 */
@RefreshScope
@Slf4j
@Service
public class GoodsCenterForChuangjiServiceImpl implements GoodsCenterForChuangjiService {

    @Value("${third-party.chuangjiCloud.url}")
    private String url;

    @Value("${third-party.chuangjiCloud.appKey}")
    private String appKey;

    @Value("${third-party.chuangjiCloud.appSecret}")
    private String appSecret;

    @Value("${third-party.chuangjiCloud.token}")
    private String token;

    @Value("${third-party.chuangjiCloud.aesKey}")
    private String aesKey;

    @Value("${third-party.chuangjiCloud.tenantId}")
    private String tenantId;

    @Resource
    private PhBrandService phBrandService;

    @Resource
    private InventoryApiService inventoryApiService;

    @Resource
    private InventoryService inventoryService;

    @Resource
    private PhCategoryService phCategoryService;

    @Resource
    private GoodsDataCreateorupdateLogService goodsDataCreateorupdateLogService;

    @Resource
    DingTalkHandler dingTalkHandler;

    /**
     * 推送创纪云
     *
     * @param inventoryId
     */
    @Override
    public Boolean phInventoryUpdateToChuangji(Long inventoryId)  {
        log.info("推送创纪云入参为:{}", inventoryId);
        long l = System.currentTimeMillis();
        // 组装数据
        Map<String, Object> map = assemblyData(Arrays.asList(inventoryId));
        // 发送请求
        String reslut = sendUrl(JSON.toJSONString(map));
        log.info("推送创纪云一次,发送请求的耗时:{}",(System.currentTimeMillis()-l));
        Boolean success = false;
        if (StringUtils.isNotBlank(reslut)) {
            success = Boolean.valueOf(JSONUtil.parseObj(reslut).get("success").toString());
        }
        // 记录日志
        saveLog(inventoryId, success, reslut);
        log.info("推送创纪云一次耗时:{}", (System.currentTimeMillis()-l));
        return success;
    }

    @Override
    public String phInventoryUpdateToChuangji(List<Long> inventoryIds) {

        log.info("推送创纪云入参为:{}", inventoryIds);
        // 组装数据
        Map<String, Object> map = assemblyData(inventoryIds);
        // 发送请求
        String reslut = sendUrl(JSON.toJSONString(map));

        return reslut;
    }

    /**
     * 校验推送结果,如果失败则记录日志
     *
     * @param inventoryId
     * @param success
     * @param reslut
     */
    private void saveLog(Long inventoryId, Boolean success, String reslut) {
        if (BooleanUtils.isFalse(success)) {
            Inventory inventory = inventoryService.getById(inventoryId);
            GoodsDataCreateorupdateLog goodsDataCreateorupdateLog = goodsDataCreateorupdateLogService
                    .getLog(inventory.getInventoryCode(), "chuangjiCloud");
            if (ObjectUtils.isEmpty(goodsDataCreateorupdateLog)) {
                goodsDataCreateorupdateLogService.saveLog(
                        "chuangjiCloud",
                        "推送创纪云商品信息失败," + reslut,
                        inventory.getInventoryCode(),
                        null);
            }
            // 对接钉钉保障提醒
            String msg = dingTalkHandler.getMsgForChuangjiCloud(reslut, inventory.getInventoryCode());
            dingTalkHandler.sendMsg(msg, new ArrayList());
        }
    }

    private String sendUrl(String body) {
        StringBuilder result = new StringBuilder();
        Random random = new Random(System.currentTimeMillis());
        String nonce = String.valueOf(Math.abs(random.nextLong()));

        SignProp signProp = new SignProp()
                .setTenantId(tenantId)
                .setAppKey(appKey)
                .setAppSecret(appSecret)
                .setAesKey(aesKey)
                .setToken(token)
                .setIv(Hex.encodeHexString(ReqEncryptUtil.generateIv()))
                .setNonce(nonce)
                .setReqTime(System.currentTimeMillis());
        String hexBody = ReqEncryptUtil.hexAesBody(body, signProp.getIv(), signProp.getAesKey());
        String sign = ReqEncryptUtil.buildSign(hexBody, signProp);
        log.info("推送创纪云的签名为:{}", sign);

        String path = url + "?_platform_num=" + signProp.getTenantId()
                + "&appKey=" + signProp.getAppKey()
                + "&_token=" + signProp.getToken()
                + "&nonce=" + signProp.getNonce()
                + "&reqTime=" + signProp.getReqTime()
                + "&_iv=" + signProp.getIv()
                + "&sign=" + sign;
        log.info("推送创纪云请求地址为:{}", path);
        try {
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setRequestProperty("Content-Type", "application/json+cipher");
            PrintWriter pw = new PrintWriter(new BufferedOutputStream(conn.getOutputStream()));
            pw.write(hexBody);
            pw.flush();
            pw.close();
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = br.readLine()) != null) {
                result.append(line).append("\n");
            }
            conn.disconnect();
            log.info("推送创纪云结果为:{}", result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("推送创纪云异常:{}，参数为:{}", e, hexBody);
        } finally {
            return StringUtils.isBlank(result) ? null : result.toString();
        }
    }

    public String subStr(String str,Integer length) {
        if(StringUtils.isBlank(str)){
            return str;
        }
        StringBuffer buffer = new StringBuffer();
        char[] chars = str.toCharArray();
        char c;
        for (int i = 0;; i++) {
            if (length <= 0) {
                break;
            }
            c = str.charAt(i);
            buffer.append(c);
            length -= String.valueOf(c).getBytes().length;
            if (i + 1 < chars.length) {
                if (String.valueOf(chars[i + 1]).getBytes().length > length) {
                    break;
                }
            }
        }
        return buffer.toString();
    }

    public String subString(String str,Integer length){
        if(StringUtils.isBlank(str)){
            return str;
        }
        if(str.length() < length){
            return str;
        }
        return str.substring(0,length);
    }

    public Map<String, Object> assemblyData(List<Long> inventoryIds) {
        List<Map<String, Object>> list = new ArrayList<>();
        inventoryIds.stream().forEach(inventoryId -> {
            Map<String, Object> bodyMap = new HashMap<>();
            List<PhPropertyVo> propertyList = new ArrayList<>();// 属性集合
            // 根据id查询货品详情
            long startquery = System.currentTimeMillis();
            PhInventoryDetailVo inventory = inventoryApiService
                    .getInventoryDetailById(inventoryId, YesOrNoEnum.YES.getCode());
            log.info("查询商品一次耗时:{}",(System.currentTimeMillis()-startquery));
            bodyMap.put("barCode", inventory.getInventoryCode());
            bodyMap.put("goodsName", inventory.getInventoryName());
            if (ObjectUtils.isNotEmpty(inventory.getPhMaterialVo())) {
                bodyMap.put("goodsSpec", inventory.getPhMaterialVo().getSeriesName());// 系列
                bodyMap.put("goodsNo", subString(inventory.getPhMaterialVo().getModelName(),32));// 型号
                bodyMap.put("wsPrice", inventory.getPhMaterialVo().getOfficialPrice() == null ? 0.00 :
                        inventory.getPhMaterialVo().getOfficialPrice());// 官网售价
                // 物料属性
                if (CollectionUtils.isNotEmpty(inventory.getPhMaterialVo().getMaterialPropertyValueList())) {
                    propertyList.addAll(inventory.getPhMaterialVo().getMaterialPropertyValueList());
                }
            } else {
                bodyMap.put("wsPrice", 0.00);// 官网售价
            }
            if (inventory.getBrandId() != null) {
                PhBrand brand = phBrandService.getById(inventory.getBrandId());
                bodyMap.put("brandCode", brand.getBrandCode());
            }
            if (inventory.getCategoryId() != null) {
                PhCategory phCategory = phCategoryService.getById(inventory.getCategoryId());
                bodyMap.put("categoryCode2", phCategory.getCode());
            }
            bodyMap.put("durability", StringUtils.isBlank(inventory.getQualityValue())
                    || ("未定义").equals(inventory.getQualityValue()) ?
                    99 : inventory.getQualityValue().replace("新", ""));// 成色
            bodyMap.put("purchPrice", inventory.getGoodsInfoForInevntoryVo().getInventoryCost() == null ? 0.00 :
                    inventory.getGoodsInfoForInevntoryVo().getInventoryCost());// 货品成本
            bodyMap.put("minsaleprice", inventory.getGoodsInfoForInevntoryVo().getSupplyTaxPrice() == null ? 0.00 :
                    inventory.getGoodsInfoForInevntoryVo().getSupplyTaxPrice());// 供货价
            bodyMap.put("salePrice", inventory.getGoodsInfoForInevntoryVo().getSaleTaxPrice() == null ? 0.00 :
                    inventory.getGoodsInfoForInevntoryVo().getSaleTaxPrice());// 销售价
            bodyMap.put("origin", inventory.getProvenance());// 产地
            if (StringUtils.isNotBlank(inventory.getYear())) {
                Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
                bodyMap.put("year", pattern.matcher(inventory.getYear()).matches() ? inventory.getYear() : "");// 年份
            }
            bodyMap.put("remark", inventory.getFlaw());//备注
            List<PhInventoryAccessoryVo> annexList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(inventory.getAnnexList())) {
                annexList.addAll(inventory.getAnnexList());
            }
            if (CollectionUtils.isNotEmpty(inventory.getAccessoryList())) {
                annexList.addAll(inventory.getAccessoryList());
            }
            bodyMap.put("qualityCondition", annexList.stream()
                    .map(PhInventoryAccessoryVo::getDictItemLabel)
                    .collect(Collectors.joining(",")));// 附件配件
            if (CollectionUtils.isNotEmpty(inventory.getPhPropertList())) {
                propertyList.addAll(inventory.getPhPropertList());
            }
            Map<String, String> propertyMap = propertyList.stream()
                    .collect(Collectors.toMap(PhPropertyVo::getPropertyName, PhPropertyVo::getPropertyValue));
            if (propertyMap.containsKey("尺寸")) {
                bodyMap.put("size", propertyMap.get("尺寸"));// 尺寸
            }
            if (propertyMap.containsKey("表径")) {
                bodyMap.put("size", propertyMap.get("表径"));// 尺寸
            }
            if (propertyMap.containsKey("测量尺寸")) {
                bodyMap.put("size", propertyMap.get("测量尺寸"));// 尺寸
            }
            if (propertyMap.containsKey("尺码")) {
                bodyMap.put("size", propertyMap.get("尺码"));// 尺寸
            }
            if (propertyMap.containsKey("规格")) {
                bodyMap.put("size", propertyMap.get("规格"));// 尺寸
            }
            if (propertyMap.containsKey("外表材质")) {
                bodyMap.put("quality", propertyMap.get("外表材质"));// 材质
            }
            if (propertyMap.containsKey("表壳材质")) {
                bodyMap.put("quality", propertyMap.get("表壳材质"));// 材质
            }
            if (propertyMap.containsKey("材质")) {
                bodyMap.put("quality", propertyMap.get("材质"));// 材质
            }
            if (propertyMap.containsKey("外表颜色")) {
                bodyMap.put("color", propertyMap.get("外表颜色"));// 颜色
            }
            if (propertyMap.containsKey("表盘颜色")) {
                bodyMap.put("color", propertyMap.get("表盘颜色"));// 颜色
            }
            if (propertyMap.containsKey("颜色")) {
                bodyMap.put("color", propertyMap.get("颜色"));// 颜色
            }
            list.add(bodyMap);
        });
        Map<String, Object> req = new HashMap<>();
        req.put("data", list);
        log.info("推送创纪云的数据为:{}", req);
        return req;
    }
}
